package filters

import (
	"cubeAdmin/common"
	"cubeAdmin/common/jwtauth"
	"cubeAdmin/common/redis"
	gstr "cubeAdmin/common/utils/gstr"
	"cubeAdmin/controllers"
	"cubeAdmin/models"
	"encoding/json"
	"github.com/beego/beego/v2/core/logs"
	beego "github.com/beego/beego/v2/server/web"
	"github.com/beego/beego/v2/server/web/context"
	_ "github.com/go-sql-driver/mysql"
	"strings"
)

type FilterChainBuilder struct{}

func (builder *FilterChainBuilder) Permission(next beego.FilterFunc) beego.FilterFunc {
	return func(ctx *context.Context) {
		url := ctx.Input.URL()
		//API 增加 CORS 支持
		ctx.Output.Header("Access-Control-Allow-Origin", "*")
		ignoreUrls, _ := beego.AppConfig.String("ignore_urls")
		if strings.Contains(ignoreUrls, url) || strings.Contains(url, "/swagger") || strings.Contains(url, "/static") {
			next(ctx)
		} else {
			method := strings.ToLower(ctx.Input.Method())

			//部署线上开启
			//prohibit := "post,put,delete"
			//if url != "/system/auth/logout" && strings.Contains(prohibit, method) {
			//	ctx.Output.JSON(controllers.ErrMsg("演示环境禁止操作", common.NotAcceptable),
			//		true, true)
			//	return
			//}

			//内部路由查询 token
			myToken := ctx.GetCookie("token")

			//调用Api时需要携带 token
			if gstr.Eq(myToken, "") {
				//http 请求
				myToken = ctx.Input.Header("token")

				//WebSocket 协议 请求携带的token
				protocol := ctx.Input.Header("Sec-WebSocket-Protocol")
				//webSocket
				if gstr.Eq(myToken, "") {
					myToken = protocol
				}
			}

			if len(myToken) < common.BearerLength {
				ctx.Output.Status = common.Unauthorized
				ctx.Output.JSON(controllers.ErrMsg("header Authorization has not Bearer token", common.Unauthorized),
					true, true)
				return
			}
			token := strings.TrimSpace(myToken[common.BearerLength:])
			usr, err := jwtauth.ValidateToken(token)
			if err != nil {
				//token 过期直接移除
				var key = common.RedisPrefixAuth + token
				redis.Rd.Del(key)
				ctx.Output.Status = common.Unauthorized
				ctx.Output.JSON(controllers.ErrMsg(err.Error(), common.Unauthorized),
					true, true)
				return
			}
			//校验权限
			index := checkPermission(url, method, token)
			if index == -1 {
				//ctx.Redirect(302,beego.URLFor("LoginController.LoginIn"))
				//redirect(beego.URLFor("HomeController.Index"))
				ctx.Output.JSON(controllers.ErrMsg("无权限", common.Unauthorized), true, true)
				return
			}
			ctx.Input.SetData(common.ContextKeyUserObj, usr)
			next(ctx)
		}
	}
}

// 验证权限
func checkPermission(url string, method string, token string) int {
	//logs.Info(url, method, token, method)
	//公共路由直接放行
	//var ignoreUrls = "/system/notice/notice,/system/menu/build,/system/user/center,/system/user/updatePass,/system/auth/info,/system/auth/logout"
	var ignoreUrls = "/system/user/center,/system/user/updatePass,/system/auth/info,/system/auth/logout"
	if strings.Contains(ignoreUrls, url) {
		return 0
	}
	// TODO 更多路由回调可自行实现
	//reg := regexp.MustCompile(`[0-9]+`)
	//newUrl := reg.ReplaceAllString(url, "*")
	//permission := models.FindByRouterAndMethod(newUrl, method)
	var key = common.RedisPrefixAuth + token
	userMap, _ := redis.Rd.Get(key)
	user := &models.SysUser{}
	unmarshal := json.Unmarshal([]byte(userMap), user)

	if unmarshal != nil {
		logs.Error("json unmarshal：json字符转解析失败")
	}
	//index := utils.Contains(user.Permissions, permission)
	if user.Id == 0 {
		return -1
	}
	return 0
}
